package top.kaoshanji.ch01.streams;

import com.google.common.io.Resources;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * 代码清单 ch01-02：创建流的方式(1.2节)
 * author kaoshanji
 * ^_^
 * create time 2024/12/5 10:17
 */
public class CreatingStreams {

    private static final Logger logger = LogManager.getLogger(CreatingStreams.class);

    static final String FILE_NAME = "gutenberg/alice30.txt";

    public static void main(String[] args) throws IOException {
        logger.info("...代码清单 ch01-02：创建流的方式(1.2节)...");

        // 【例1】如果已经有数据了
        String fileContent = Resources.toString(Resources.getResource(FILE_NAME), StandardCharsets.UTF_8);
        Stream<String> words = Stream.of(fileContent.split("\\PL+"));
        show("words", words);
        Stream<String> song = Stream.of("gently", "down", "the", "stream");
        show("song", song);

        // 【例2】一个空的流
        Stream<String> silence = Stream.empty();
        show("silence", silence);

        // 【例3】无限流
        Stream<String> echos = Stream.generate(() -> "Echo");
        show("echos", echos);
        Stream<Double> randoms = Stream.generate(Math::random);
        show("randoms", randoms);

        // 【例4】产生像 0 1 2 3 ...这样的序列
        Stream<BigInteger> integers = Stream.iterate(BigInteger.ONE, n -> n.add(BigInteger.ONE));
        show("integers", integers);

        // 【例5】正则表达式
        Stream<String> wordsAnotherWay = Pattern.compile("\\PL+").splitAsStream(fileContent);
        show("wordsAnotherWay", wordsAnotherWay);

        // 【例6】持有的Iterable对象不是集合
        Iterable<Path> iterable = FileSystems.getDefault().getRootDirectories();
        Stream<Path> rootDirectories = StreamSupport.stream(iterable.spliterator(), false);
        show("rootDirectories", rootDirectories);

    }

    public static <T> void show(String title, Stream<T> stream) {

        final int SIZE = 10;
        List<T> firstElements = stream.limit(SIZE + 1).collect(Collectors.toList());

        System.out.print(title + ": ");
        for (int i = 0; i < firstElements.size(); i++) {
            if (i > 0) System.out.print(", ");
            if (i < SIZE) {
                System.out.print(firstElements.get(i));
            } else {
                System.out.print("...");
            }
        }

        System.out.println();

    }

}
